<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/*
* 使用方法:
*
* read:
* $this->load->library('zmexcel');
* $this->zmexcel->checkExcelFile($info['file']); //check
* $this->zmexcel->init($file); //excel file
* $data = $this->zmexcel->getDatas(); //return data (aleady unset data[1]),if params is false,not unset;
*
* writer:
*		$this->load->library('zmexcel');
*		$this->zmexcel->init();
*		$this->zmexcel->setTitle(array(
*			array('content'=>'顾客ID1'),
*			array('content'=>'顾客ID2','child' => array(
*				array('content'=>'顾客ID2_1'),
*				array('content'=>'顾客ID2_2','child'=>array(
*					array('content' => 'xx1','color'=>Zmexcel::COLOR_GREEN),
*					array('content' => 'xx2')
*				)),
*			)),
*			array('content'=>'顾客ID3','color'=>Zmexcel::COLOR_BLUE),
*			array('content'=>'顾客ID4'),
*		));
*
*		for ($i=0; $i < 3; $i++) {
*			$this->zmexcel->addRow(array(
*				array('content' => 'id1_'.$i),
*				array('content' => 'id2_1_'.$i,'color'=>Zmexcel::COLOR_RED),
*				array('content' => 'id2_2_XX1_'.$i),
*				array('content' => 'id2_2_XX2_'.$i),
*				array('content' => 'id3_'.$i),
*				array('content' => 'id$_'.$i),
*			));
*		}
*		$this->zmexcel->generate('t.xls');
*/

include APPPATH.'third_party/PHPExcel/PHPExcel.php';
include APPPATH.'third_party/PHPExcel/PHPExcel/IOFactory.php';
include APPPATH.'third_party/PHPExcel/PHPExcel/Writer/Excel5.php';
@set_time_limit(0);
@ini_set('memory_limit', '3000M');

class Zmexcel {

	protected $_objPHPExcel;
	protected $_objReader;
	protected $_objWriter;
	protected $_filepath;

	protected $_current_sheet;
	protected $_CI;

	protected $_sheet_name = '';
	protected $_title_arr = array();
	protected $_content_arr = array();

	protected $_freeze_row = -1;
	protected $_freeze_col = 0;

	protected $_max_title_depth = -1;
	protected $_not_use_freeze = false;

	const COLOR_BLACK						= 'FF000000';
	const COLOR_WHITE						= 'FFFFFFFF';
	const COLOR_RED							= 'FFFF0000';
	const COLOR_DARKRED						= 'FF800000';
	const COLOR_BLUE						= 'FF0000FF';
	const COLOR_DARKBLUE					= 'FF000080';
	const COLOR_GREEN						= 'FF00FF00';
	const COLOR_DARKGREEN					= 'FF008000';
	const COLOR_YELLOW						= 'FFFFFF00';
	const COLOR_DARKYELLOW					= 'FF808000';

	//Compatible
	const STYLE_NORMAL = 'FFFFFFFF';
	const STYLE_GREEN = 'FF00FF00';
	const STYLE_PURPLE = 'FFFF00FF';
	const STYLE_BLUE = 'FF0000FF';
	const STYLE_ORANGE = 'FF808000';
	const STYLE_WHEAT = 'FF4D3900';

	//format
	const CELL_WIDTH_DEFAULT = 20;
	const CELL_HEIGHT_DEFAULT = 20;

	public function __construct(){
		$this->_CI = & get_instance();
	}

	public function init($filepath='') {
		if(empty($filepath) || stripos($filepath, '/') === false) {
			$this->_objPHPExcel = new PHPExcel();
			$this->_current_sheet = $this->_objPHPExcel->getActiveSheet();
			$this->_current_sheet->getDefaultColumnDimension()->setWidth(Zmexcel::CELL_WIDTH_DEFAULT);
			$this->_current_sheet->getDefaultRowDimension()->setRowHeight(Zmexcel::CELL_HEIGHT_DEFAULT);
			$styleArray = array(
				'borders' => array(
					'allborders' => array(
					'style' => PHPExcel_Style_Border::BORDER_THIN
				)
			));

			// $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;
			// PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
			$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
			if (!PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {
				die($cacheMethod . " caching method is not available" . EOL);
			}


			$this->_objPHPExcel->getDefaultStyle()->applyFromArray($styleArray);
		} else {
			$this->_objReader = PHPExcel_IOFactory::createReaderForFile($filepath);
			$this->_objReader->setReadDataOnly(true);
			$this->_objPHPExcel = $this->_objReader->load($filepath);
			$this->_current_sheet = $this->_objPHPExcel->getActiveSheet();
		}
		$this->_filepath = $filepath;
		return $this;
	}

	public function checkExcelFile($file) {
		if($file['type'] != 'application/excel'
			&& $file['type'] != 'application/vnd.ms-excel'
			&& $file['type'] != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
			$this->_CI->response->setDetail('请上传excel文件');
			$this->_CI->response->responseExit();
		}
	}

	public function getDatas($remove_title = true) {
		$datas = $this->_current_sheet->toArray('',true,true,true);
		if($remove_title) {
			array_shift($datas);
		}
		$this->_objPHPExcel->disconnectWorksheets();
    	unset($this->_objPHPExcel);
		return $datas;
	}

	public function setSheetName($sheet_name) {
		$this->_sheet_name = $sheet_name;
		return $this;
	}

	public function addSheet($sheet_name) {
		$this->_sheet_name = $sheet_name;
		return $this;
	}

	public function setFreezeRow($freeze_row) {
		$this->_freeze_row = $freeze_row;
		return $this;
	}

	public function setFreezeCol($freeze_col) {
		$this->_freeze_col = $freeze_col;
		return $this;
	}

	public function setTitle($title_arr) {
		$this->_title_arr = $title_arr;
		return $this;
	}

	public function addTitle($title_arr) {
		$this->_title_arr = $title_arr;
		return $this;
	}

	public function addRow($row_arr) {
		$this->_content_arr[] = $row_arr;
		return $this;
	}

	public function setNotUseFreeze($status = false) {
		$this->_not_use_freeze = $status;
		return $this;
	}

	public function freezePanes($freeze_row = 0,$freeze_col = 0) {
		$this->_freeze_row = $freeze_row;
		$this->_freeze_col = $freeze_col;
		return $this;
	}

	public function generate($filename = '') {
		if(!empty($filename)) {
			$this->_filepath = $filename;
		}
		$this->_outputFile();
		exit;
	}

	private function _outputFile() {
		$col = 0;
		$row_index = 1;
		$depth = 0;
		$this->_max_title_depth = array_depth($this->_title_arr);
		foreach($this->_title_arr as $it) {
			list($col,$d) = $this->_setChildTitle($it,$row_index,$col,0);
			$depth = max($d,$depth);
		}
		unset($this->_title_arr);

		$row_index = $depth;
		foreach ($this->_content_arr as $key => $value) {
			$row_index++;
			foreach ($value as $k => $v) {
				$this->_current_sheet->setCellValueByColumnAndRow($k, $row_index, $v['content']);
				if(!empty($v['color'])) {
					$this->_setBackgrounColor($k, $row_index,$v['color']);
				}
			}
			unset($this->_content_arr[$key]);
		}

		if(!$this->_not_use_freeze) {
			$freeze_col = $this->_freeze_col >= 0 ? $this->_freeze_col : $col;
			$freeze_row = $this->_freeze_row > 0 ? $this->_freeze_row : $depth+1;
			$this->_current_sheet->freezePaneByColumnAndRow($freeze_col,$freeze_row);
		}
		// $this->_current_sheet->freezePane('A2');

		$this->_filepath = rtrim($this->_filepath,'xls').'xlsx';
		header("Pragma: public");
	    header("Expires: 0");
	    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
		header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
	    header("Content-Type: application/force-download");
	    header("Content-Type: application/octet-stream");
	    header("Content-Type: application/download");

	    $ua = $_SERVER["HTTP_USER_AGENT"];
	    $filename = $this->_filepath;

	    $encoded_filename = urlencode($filename);
		$encoded_filename = str_replace("+", "%20", $encoded_filename);
		if (preg_match("/MSIE/", $ua) || preg_match('/Trident\/7.0/i', $ua)) {
			header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
		} else if (preg_match("/Firefox/", $ua)) {
			header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"');
		} else {
			header('Content-Disposition: attachment; filename="' . $filename . '"');
		}

	    header("Content-Transfer-Encoding: binary ");
	   	$this->_objWriter = PHPExcel_IOFactory::createWriter($this->_objPHPExcel, 'Excel2007');
	   	$this->_objWriter->setOffice2003Compatibility(true);
    	$this->_objWriter->save('php://output');
    	$this->_objPHPExcel->disconnectWorksheets();
    	unset($this->_objPHPExcel);
    	exit();
	}

	private function _setChildTitle($item,$row_index,$col,$depth) {
		$depth++;
		if(!empty($item['child'])){
			$o_col = $col;
			$o_depath = $depth;
			foreach($item['child'] as $it){
				list($col,$d) = $this->_setChildTitle($it,$row_index+1,$col,$o_depath);
				$depth = max($d,$depth);
			}
			$this->_current_sheet->setCellValueByColumnAndRow($o_col, $row_index, $item['content']);
			$this->_current_sheet->mergeCells(
					PHPExcel_Cell::stringFromColumnIndex($o_col).$row_index.':'.
					PHPExcel_Cell::stringFromColumnIndex($col-1).$row_index
				);
			if(!empty($item['color'])) {
				$this->_setBackgrounColor($o_col, $row_index,$item['color']);
			}
			return array($col,$depth);
		} else {
			$this->_current_sheet->setCellValueByColumnAndRow($col, $row_index, $item['content']);
			if(!empty($item['color'])) {
				$this->_setBackgrounColor($col, $row_index,$item['color']);
			}
			if($this->_max_title_depth > $row_index) {
				$this->_current_sheet->mergeCells(
					PHPExcel_Cell::stringFromColumnIndex($col).$row_index.':'.
					PHPExcel_Cell::stringFromColumnIndex($col).$this->_max_title_depth
				);
			}
		}
		return array($col+1,$depth);
	}

	private function _setBackgrounColor($col,$row,$color) {
		$this->_current_sheet->getStyleByColumnAndRow($col, $row)
			->getFill()
			->setFillType(PHPExcel_Style_Fill::FILL_SOLID)
			->getStartColor()->setARGB($color);
	}
}

/* End of file excel.php */
/* Location: ./application/libraries/excel.php */
